iT邦幫忙

0

(8) 研發看 MES:產品是由基礎資料組合而成的

mes
  • 分享至 

  • xImage
  •  

研發看 MES:產品是由基礎資料組合而成的

前面幾天,我們陸續建立了:

Machine
Process
Route
Customer

一路做到這裡,每一個功能看起來都還算獨立。
Machine 負責定義有哪些機台。
Process 負責定義有哪些製程。
Route 把多個 Process 按照 SEQ 串成生產流程。
Customer 則記錄客戶與聯絡人資料。

今天要開始建立下一個重要的 Master Data:
Product(產品)。

做到 Product 之後,前面建立的基礎資料也開始慢慢有「組合起來」的感覺。
因為後面建立 Work Order 時,我們不能只告訴 MES:

我要生產 1000 PCS。

還必須知道:

到底要生產什麼?

Product 最基本需要記什麼?

先從最簡單的 Product 開始。
例如:

PRODUCT
-------------------------
PRODUCT_UUID
PRODUCT_CODE
PRODUCT_NAME
ENABLE
CREATE_TIME
UPDATE_TIME

建立幾個產品:

PDT-001    Product A
PDT-002    Product B
PDT-003    Product C

到這裡,其實跟 Machine 一樣。
所以真正值得看的,是:
Product 接下來會怎麼被其他資料使用。

Product 不只是「產品名稱」

假設我們現在有兩個產品:

Product A
Product B

從 MES 的角度來看,它們不能只是兩個名稱不同的字串,因為不同產品可能有不同的生產方式。
例如:

Product A
↓
Route A (① → ② → ③ → ④)

另外一個產品:

Product B
↓
Route B (① → ③ → ⑤)

雖然工廠裡使用的是同一套 MES,但是不同產品不一定走完全相同的生產流程。

所以當我們建立 Product 時,產品資料就開始跟前面建立的:
Route
產生關係。

Product 與 Route

假設前面已經建立兩條 Route:

ROUTE-A

10 → Die Attach
20 → Wire Bond
30 → Molding
40 → Inspection

以及:

ROUTE-B

10 → Die Attach
20 → Molding
30 → Inspection

接下來建立:

Product A

並指定:

Product A
    ↓
Route A

另外:

Product B
    ↓
Route B

這樣 Product 就不再只是一筆:

PRODUCT_CODE + PRODUCT_NAME

而開始帶有一部分:

這個產品應該怎麼生產。
的資訊。

為什麼不是直接把 Process 綁在 Product?

這裡可能會有一個問題。

既然 Product 最後就是要經過:

Die Attach
Wire Bond
Molding
Inspection

那為什麼 Product 不直接綁 Process?

例如:

Product A
├── Die Attach
├── Wire Bond
├── Molding
└── Inspection

問題是:
只有 Process 還不夠,我們還需要知道順序。

Die Attach → Wire Bond → Molding → Inspection

而這件事情其實Route已經處理好了。
所以我們不需要在 Product 再重新定義一次。
而是:

Process
   ↓
Route
   ↓
Product

Route 負責管理:

製程有哪些、順序怎麼走。

Product 則直接使用已經建立好的 Route。
這也是為什麼前面的開發順序很重要。

如果一開始先做 Product 呢?

假設我沒有先做 機台、製程、途程

而是直接跑來做 Product。
Product 畫面上出現:

產品代碼:PDT-001

產品名稱:Product A

生產途程:[ 請選擇 ]

問題馬上就來了。

下拉選單裡要放什麼?

因為:

ROUTE

根本還不存在。

當然我們可以先:

route_list = [
    "ROUTE-A",
    "ROUTE-B",
    "ROUTE-C"
]

直接寫死。
也可以先建立幾筆假的測試資料。

但如果今天是從零開始建立一套 MES,我會更傾向:

先完成底層資料
        ↓
再讓上層功能使用

所以前面的開發順序才會是:

Machine
   ↓
Process
   ↓
Route
   ↓
Product

現在做到 Product 時,畫面上的 Route 選單終於可以真的從 Database 取得。

下拉選單其實也是 Dependency

從使用者的角度來看:

Route:[ ROUTE-A ▼ ]

只是一個很普通的下拉選單。

但從研發的角度來看,它其實代表:

Product
   │
   └── depends on Route

也就是:
Dependency(依賴)。

Product 需要 Route。

所以建立 Product 時,後端不能只相信前端送過來的:

{
    "product_code": "PDT-001",
    "route_uuid": "ROUTE-UUID-001"
}

我們還需要確認:

ROUTE-UUID-001

真的存在。

前端有下拉選單,為什麼後端還要檢查?

有些人可能會覺得:

Route 都是從下拉選單選的,使用者又不能亂輸入,後端還需要檢查嗎?
還是需要。

因為 API 不一定只能從這個畫面呼叫。

而且在使用者打開畫面到按下儲存之間,資料狀態也可能已經發生變化。
例如:

使用者打開 Product 頁面
        ↓
載入 ROUTE-A
        ↓
另外一個使用者停用 ROUTE-A
        ↓
第一個使用者按下儲存

這時候前端手上的:

ROUTE-A

已經是舊資料。

所以後端還是需要重新確認:

route = get_route(data["route_uuid"])

if route is None:
    raise Exception("Route not found.")

if not route.enable:
    raise Exception("Route is disabled.")

這也是我在開發這類系統時很常碰到的一個觀念:

前端 Validation 是為了使用體驗,後端 Validation 才是最後一道資料防線。

Product Code 一樣不能亂改

Product 還有另外一個很重要的欄位:

PRODUCT_CODE

例如:

PDT-001

一開始它可能只是一個普通的產品代碼。
但是後面建立 Work Order、Lot、報表之後,Product 會開始被大量使用。
例如:

WO-001
   ↓
PDT-001

接著:

LOT-001
   ↓
WO-001
   ↓
PDT-001

這時候 Product 已經不再是一筆可以隨便處理的資料。

尤其如果直接把 Product 刪掉:

DELETE PDT-001

過去的 Work Order、Lot History、Report 還要不要查得到它?
這跟前面 Machine 遇到的問題一樣。

所以對已經被使用的 Master Data,我通常會比較傾向:

PDT-001
ENABLE = False

而不是直接從 Database 消失。

Product 修改 Route,又會出現另一個問題

接下來才是 Product 比較有意思的地方。

假設:

Product A
↓
Route A

Route A 是:

① → ② → ③ → ④

今天工程人員修改 Product:

Product A
↓
Route B

Route B:

① → ③ → ⑤

對還沒開始生產的新工單來說,好像沒什麼問題。

但是如果現在工廠裡已經有:

LOT-001
LOT-002
LOT-003

正在按照:

Route A

生產呢?

難道 Product 一修改,這些 Lot 就突然全部改走 Route B?
通常不應該這麼簡單。

「現在的設定」跟「當時的設定」開始不一樣了

這裡其實跟上一篇 Route Update 遇到的問題非常像。

假設:

10/01

Product A → Route A

當天建立:

WO-001

開始生產。

到了:

10/15

Product A 改成:

Product A → Route B

那我們在 10/20 查看 WO-001 時,到底應該看到:

Route A

還是:

Route B

如果只去查 Product 現在的設定:

Product A → Route B

我們可能會錯誤地以為:

WO-001 當初也是按照 Route B 生產。

但實際上:

WO-001

建立當下使用的是:

Route A

這就是 MES 很重要的一個問題:
Current Configuration 不一定等於 Historical Configuration。

這也是為什麼後面會需要「保留當時的設定」

這篇先不急著深入實作。

因為等做到:
Work Order

以及:
Lot

時,這個問題會變得更明顯。

但現在可以先留下一個概念。

Product 是:

現在這個產品的設定

Work Order / Lot 則需要考慮:

當時生產時使用的是什麼設定

這兩件事情不能永遠假設完全相同。
否則 Master Data 一修改,歷史資料就可能跟著改變解讀方式。

Customer 跟 Product 需要直接綁在一起嗎?

現在我們已經有:

Customer

以及:

Product

很容易會想:

那是不是 Product 要直接綁 Customer?

例如:

客戶 A
   ↓
Product A

這就要看實際系統需求。

如果你的業務規則明確規定:

某個 Product 就是屬於某個 Customer。
那建立關係很合理。

但如果:

同一個 Product 可能提供給不同 Customer。
那直接綁死反而可能限制系統。

所以我不會因為:

「反正後面 Work Order 都會用到。」
就把所有 Master Data 先全部互相綁起來。
關聯越多,不代表系統設計越完整。

真正應該問的是:

這個關係是不是業務上真的存在?

如果真正需要 Customer + Product 的地方是在 Work Order:

Work Order
├── Customer
├── Product
└── Route

那就等 Work Order 再建立這個關係。
這樣每個 Master Data 的責任會比較清楚。

從研發角度看:前面的積木開始有用了

一路寫到 Product,我們可以重新看一下目前建立的東西。

最底層建立機台:

Machine

接著建立製程並與機台資料綁定:

Process
   ↕
Machine

再來途程引用製程並為他排序:

Route
   ↓
Process + SEQ

現在根據產品別,套用正確的途程:

Product
   ↓
Route
   ↓
Process
   ↓
Machine

前面花時間建立的資料,開始真的被上層功能使用。
這也是我選擇按照 Dependency 往上開發的原因。

不是因為:

Machine 比較重要,所以先做 Machine。

而是因為:

先把被依賴的東西建立好,上層功能才有真正的資料可以使用。

現在我們已經有:

Customer
Product
Route
Process
Machine

如果把這些資料想成積木,我們已經準備得差不多了。

但在真正建立 Work Order 以前,還有一個資料需要先處理:
Warehouse(倉庫)。
因為 Lot 不會永遠停留在製程裡。

生產完成之後,它可能進入:
完工倉

等待出貨時可能進入:
包裝倉

生產過程中也可能需要:
暫存倉

如果產品報廢,則可能進入:
報廢倉

而且除了系統定義的用途之外,使用者也可能建立自己的 Warehouse。

所以接下來,我們要開始處理另外一個問題:

Lot 不在製程裡的時候,它在哪裡?

下一篇:
「Lot 離開製程之後要去哪裡?」

認識我們
聯繫我們

章節列表


*提醒邦友,使用第三方服務/API 時,請務必評估資安風險與隱私保護
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言